using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 文件格式服务 - 统一管理文件保存格式
    /// </summary>
    public interface IFileFormatService
    {
        /// <summary>
        /// 保存文本内容到指定格式的文件
        /// </summary>
        Task<bool> SaveContentAsync(string filePath, string content, FileFormat format);
        
        /// <summary>
        /// 读取文件内容（自动检测格式）
        /// </summary>
        Task<string> ReadContentAsync(string filePath);
        
        /// <summary>
        /// 转换文件格式
        /// </summary>
        Task<bool> ConvertFileAsync(string sourcePath, string targetPath, FileFormat targetFormat);
        
        /// <summary>
        /// 获取支持的文件格式
        /// </summary>
        List<FileFormatInfo> GetSupportedFormats();
        
        /// <summary>
        /// 根据扩展名获取文件格式
        /// </summary>
        FileFormat GetFormatByExtension(string extension);
    }

    public class FileFormatService : IFileFormatService
    {
        private readonly ILogger<FileFormatService> _logger;

        public FileFormatService(ILogger<FileFormatService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 保存文本内容到指定格式的文件
        /// </summary>
        public async Task<bool> SaveContentAsync(string filePath, string content, FileFormat format)
        {
            try
            {
                // 确保目录存在
                var directory = Path.GetDirectoryName(filePath);
                if (!string.IsNullOrEmpty(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                switch (format)
                {
                    case FileFormat.Text:
                        await File.WriteAllTextAsync(filePath, content, Encoding.UTF8);
                        break;
                        
                    case FileFormat.Markdown:
                        await File.WriteAllTextAsync(filePath, content, Encoding.UTF8);
                        break;
                        
                    case FileFormat.Docx:
                        await SaveAsDocxAsync(filePath, content);
                        break;
                        
                    case FileFormat.Html:
                        await SaveAsHtmlAsync(filePath, content);
                        break;
                        
                    default:
                        throw new NotSupportedException($"不支持的文件格式: {format}");
                }

                _logger.LogInformation($"文件保存成功: {filePath} (格式: {format})");
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"保存文件失败: {filePath}");
                return false;
            }
        }

        /// <summary>
        /// 读取文件内容（自动检测格式）
        /// </summary>
        public async Task<string> ReadContentAsync(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                    throw new FileNotFoundException($"文件不存在: {filePath}");

                var extension = Path.GetExtension(filePath).ToLower();
                var format = GetFormatByExtension(extension);

                switch (format)
                {
                    case FileFormat.Text:
                    case FileFormat.Markdown:
                        return await File.ReadAllTextAsync(filePath, Encoding.UTF8);
                        
                    case FileFormat.Docx:
                        return ReadDocxContent(filePath);
                        
                    case FileFormat.Html:
                        return await File.ReadAllTextAsync(filePath, Encoding.UTF8);
                        
                    default:
                        // 尝试作为文本文件读取
                        return await File.ReadAllTextAsync(filePath, Encoding.UTF8);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"读取文件失败: {filePath}");
                throw;
            }
        }

        /// <summary>
        /// 转换文件格式
        /// </summary>
        public async Task<bool> ConvertFileAsync(string sourcePath, string targetPath, FileFormat targetFormat)
        {
            try
            {
                var content = await ReadContentAsync(sourcePath);
                return await SaveContentAsync(targetPath, content, targetFormat);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"文件格式转换失败: {sourcePath} -> {targetPath}");
                return false;
            }
        }

        /// <summary>
        /// 获取支持的文件格式
        /// </summary>
        public List<FileFormatInfo> GetSupportedFormats()
        {
            return new List<FileFormatInfo>
            {
                new() { Format = FileFormat.Text, Name = "纯文本", Extension = ".txt", Description = "纯文本格式，兼容性最好" },
                new() { Format = FileFormat.Markdown, Name = "Markdown", Extension = ".md", Description = "Markdown格式，支持富文本标记" },
                new() { Format = FileFormat.Docx, Name = "Word文档", Extension = ".docx", Description = "Microsoft Word格式，支持复杂排版" },
                new() { Format = FileFormat.Html, Name = "HTML", Extension = ".html", Description = "网页格式，支持富文本和样式" }
            };
        }

        /// <summary>
        /// 根据扩展名获取文件格式
        /// </summary>
        public FileFormat GetFormatByExtension(string extension)
        {
            return extension.ToLower() switch
            {
                ".txt" => FileFormat.Text,
                ".md" => FileFormat.Markdown,
                ".docx" => FileFormat.Docx,
                ".html" or ".htm" => FileFormat.Html,
                _ => FileFormat.Text
            };
        }

        /// <summary>
        /// 保存为DOCX格式
        /// </summary>
        private async Task SaveAsDocxAsync(string filePath, string content)
        {
            using var document = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document);
            
            var mainPart = document.AddMainDocumentPart();
            mainPart.Document = new Document();
            var body = mainPart.Document.AppendChild(new Body());

            // 将内容按段落分割
            var paragraphs = content.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
            
            foreach (var paragraphText in paragraphs)
            {
                var paragraph = new Paragraph();
                var run = new Run();
                var text = new Text(paragraphText);
                
                run.Append(text);
                paragraph.Append(run);
                body.Append(paragraph);
            }

            await Task.CompletedTask; // 保持异步接口一致性
        }

        /// <summary>
        /// 读取DOCX内容
        /// </summary>
        private string ReadDocxContent(string filePath)
        {
            using var document = WordprocessingDocument.Open(filePath, false);
            var body = document.MainDocumentPart?.Document?.Body;
            
            if (body == null)
                return string.Empty;

            var content = new StringBuilder();
            
            foreach (var paragraph in body.Elements<Paragraph>())
            {
                var paragraphText = paragraph.InnerText;
                content.AppendLine(paragraphText);
            }

            return content.ToString();
        }

        /// <summary>
        /// 保存为HTML格式
        /// </summary>
        private async Task SaveAsHtmlAsync(string filePath, string content)
        {
            var html = new StringBuilder();
            html.AppendLine("<!DOCTYPE html>");
            html.AppendLine("<html lang=\"zh-CN\">");
            html.AppendLine("<head>");
            html.AppendLine("    <meta charset=\"UTF-8\">");
            html.AppendLine("    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
            html.AppendLine($"    <title>{Path.GetFileNameWithoutExtension(filePath)}</title>");
            html.AppendLine("    <style>");
            html.AppendLine("        body { font-family: 'Microsoft YaHei', sans-serif; line-height: 1.6; margin: 40px; }");
            html.AppendLine("        h1, h2, h3 { color: #333; }");
            html.AppendLine("        p { margin-bottom: 1em; }");
            html.AppendLine("    </style>");
            html.AppendLine("</head>");
            html.AppendLine("<body>");
            
            // 简单的Markdown到HTML转换
            var lines = content.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
            foreach (var line in lines)
            {
                if (line.StartsWith("# "))
                {
                    html.AppendLine($"    <h1>{line.Substring(2)}</h1>");
                }
                else if (line.StartsWith("## "))
                {
                    html.AppendLine($"    <h2>{line.Substring(3)}</h2>");
                }
                else if (line.StartsWith("### "))
                {
                    html.AppendLine($"    <h3>{line.Substring(4)}</h3>");
                }
                else if (string.IsNullOrWhiteSpace(line))
                {
                    html.AppendLine("    <br>");
                }
                else
                {
                    html.AppendLine($"    <p>{line}</p>");
                }
            }
            
            html.AppendLine("</body>");
            html.AppendLine("</html>");

            await File.WriteAllTextAsync(filePath, html.ToString(), Encoding.UTF8);
        }
    }

    /// <summary>
    /// 文件格式枚举
    /// </summary>
    public enum FileFormat
    {
        Text,
        Markdown,
        Docx,
        Html
    }

    /// <summary>
    /// 文件格式信息
    /// </summary>
    public class FileFormatInfo
    {
        public FileFormat Format { get; set; }
        public string Name { get; set; } = "";
        public string Extension { get; set; } = "";
        public string Description { get; set; } = "";
    }
}
